﻿using UnityEngine;
using System.Collections;
using NewEditorNS;
using System.Collections.Generic;
using SongeNS;
using LitJson;
using FairyGUI.UI;
using ArtsWork;
using FairyGUI;
using SimpleJSON;
using System;
using Jhqc.EditorCommon;
using System.IO;

/// <summary>组件编辑状态 添加墙体/添加组件/添加绿化带</summary>
public enum EnumEditState { normal, addComp, addWall, addGreenMesh }


/// <summary>处理合模编辑的业务逻辑</summary>
public class CompEditor
{
    static CompEditor instance;
    public static CompEditor Instance
    {
        get
        {
            if (instance == null)
                instance = new CompEditor();
            return instance;
        }
    }

    ISelectable curSelect;
    public ISelectable CurSelect
    {
        get
        {
            return curSelect;
        }

        set
        {
            ISelectable oldSelect = curSelect;
            curSelect = value;
            if (oldSelect != null)
                oldSelect.ShowSelect = false;
            if (curSelect != null)
                curSelect.ShowSelect = true;
        }
    }

    public void OnCtrlPointSelect(CtrlPoint tar)
    {
        CurSelect = tar;
    }

    GameObject _compFolder;
    GameObject compFolder
    {
        get
        {
            if (_compFolder == null)
            {
                _compFolder = new GameObject();
                _compFolder.name = "compFolder";
            }
            return _compFolder;
        }
    }

    EnumEditState editState;
    public EnumEditState EditState
    {
        get
        {
            return editState;
        }

        set
        {
            editState = value;
            switch (editState)
            {
                case EnumEditState.normal:
                    MonoHelper.Instance.UpdatePointTxt(false, "");
                    break;
                case EnumEditState.addComp:
                    MonoHelper.Instance.UpdatePointTxt(true, "添加组件");
                    break;
                case EnumEditState.addWall:
                    MonoHelper.Instance.UpdatePointTxt(true, "添加墙体");
                    break;
                case EnumEditState.addGreenMesh:
                    MonoHelper.Instance.UpdatePointTxt(true, "添加绿化带");
                    break;
                default:
                    break;
            }
        }
    }

    Dictionary<string, KeyValue> expediteKeyDic = new Dictionary<string, KeyValue>();

    public CompEditor()
    {
        Init();
    }

    bool hasInited = false;
    public void Init()
    {
        if (hasInited)
            return;
        hasInited = true;

        expediteKeyDic.AddRep(UICONST.BTN_UP, new KeyValue(Vector3.up, 0));
        expediteKeyDic.AddRep(UICONST.BTN_DOWN, new KeyValue(Vector3.down, 0));

        expediteKeyDic.AddRep(UICONST.BTN_LT, new KeyValue(Vector3.up, 0));
        expediteKeyDic.AddRep(UICONST.BTN_RT, new KeyValue(Vector3.down, 0));

        expediteKeyDic.AddRep(UICONST.BTN_YMAX, new KeyValue(Vector3.down, 0));
        expediteKeyDic.AddRep(UICONST.BTN_YMIN, new KeyValue(Vector3.up, 0));
        expediteKeyDic.AddRep(UICONST.BTN_XMAX, new KeyValue(Vector3.left, 0));
        expediteKeyDic.AddRep(UICONST.BTN_XMIN, new KeyValue(Vector3.right, 0));
        expediteKeyDic.AddRep(UICONST.BTN_ZMAX, new KeyValue(Vector3.back, 0));
        expediteKeyDic.AddRep(UICONST.BTN_ZMIN, new KeyValue(Vector3.forward, 0));

        expediteKeyDic.AddRep(UICONST.BTN_SMAX, new KeyValue(new Vector3(-1, -1, -1), 0));
        expediteKeyDic.AddRep(UICONST.BTN_SMIN, new KeyValue(new Vector3(1, 1, 1), 0));

        expediteKeyDic.AddRep(UICONST.BTN_ONE, new KeyValue(Vector3.one, 0));
    }

    public void OnEvent(string eventName, object param)
    {
        switch (eventName)
        {

            case UICONST.MATEDITIONEND:
                GameObject tar = param as GameObject;
                if (tar != null)
                {
                    CompVO comp = tar.GetComponentInParent<CompVO>();
                    if (comp != null && comp.CompType == EnumCompType.greenMesh)
                        comp.RecordGreenMeshMat(tar);
                }
                break;
            case UICONST.COMPCLICKED:
                OnCompIconClick(param as CompIconVO);
                break;
            case UICONST.EventInputChange:
                string inputName = param.ToString();
                OnInputSubmit(inputName);
                break;
            case UICONST.EventBtnPress:

                BtnPressTime bpt = param as BtnPressTime;
                if (bpt != null)
                {
                    switch (bpt.BtnName)
                    {
                        case UICONST.BTN_LT:
                        case UICONST.BTN_RT:
                        case UICONST.BTN_UP:
                        case UICONST.BTN_DOWN:
                        case UICONST.BTN_SMAX:
                        case UICONST.BTN_SMIN:
                        case UICONST.BTN_XMAX:
                        case UICONST.BTN_XMIN:
                        case UICONST.BTN_YMAX:
                        case UICONST.BTN_YMIN:
                        case UICONST.BTN_ZMAX:
                        case UICONST.BTN_ZMIN:
                            OnBtnPress(bpt);
                            break;
                    }
                }
                break;
            case UICONST.EventToggleChange:
                SEvent<string, object> se = param as SEvent<string, object>;
                if (se != null)
                {
                    if (se.Param1 == UICONST.TOGGLE_EDITION)
                        CtrlPointManager.Instance.ShowCtrlPoint = (bool)se.Param2;
                    else if (se.Param1 == UICONST.TOGGLE_SCALE)
                    {
                        if (CurSelect is CtrlPoint)
                        {
                            CtrlPoint cp = CurSelect as CtrlPoint;
                            CompVO comp = CtrlPointManager.Instance.GetCompByCtrlPoint(cp);
                            if (comp != null && comp.CompType == EnumCompType.wall)
                            {
                                comp.theWallVO.needScaleTail = (bool)se.Param2;
                                //comp.CreateModel();
                                comp.RefreshModel();
                            }
                        }
                    }
                }
                break;
            case UICONST.EventBtnClick:
                switch (param.ToString())
                {
                    case UICONST.BTN_DELETE:
                    case UICONST.BTN_ONE:
                    case UICONST.BTN_POINT:
                    case UICONST.BTN_DISMANTLE:
                    case UICONST.BTN_SAVE:
                    case UICONST.BTN_GREENMESH:
                    case UICONST.BTN_SUBMIT:
                    case UICONST.BTN_REPLACE:
                    case UICONST.BTN_REPLACE_ALL:
                    case UICONST.BTN_CLONE:
                        OnBtnClick(param.ToString(), param);
                        break;
                }
                break;
            case UICONST.Roam_BestBlocksAdd:
                {
                    Block block = param as Block;
                    if (MonoHelper.Instance.IsCruise)
                    {
                        string routeID = ShopEditor.Instance.GetRouteIDFromBlockName(block.name);
                        if (!string.IsNullOrEmpty(routeID))
                        {
                            ShopEditor.Instance.OnRoamLoadShops(routeID);
                        }
                    }
                }
                break;
            case UICONST.Roam_BestBlocksRemove:
                {
                    Block block = param as Block;
                    if (MonoHelper.Instance.IsCruise)
                    {
                        string routeID = ShopEditor.Instance.GetRouteIDFromBlockName(block.name);
                        if (!string.IsNullOrEmpty(routeID))
                        {
                            ShopEditor.Instance.OnRoamUnLoadShops(routeID);
                        }
                    }
                }
                break;

        }
    }

    public void OnMouseEvent(MouseEvent me)
    {
        switch (me.eventType)
        {
            case MouseEvent.MouseDown:
                //Debug.Log("MouseDown");
                OnSceneMouseDown(me);
                break;
            case MouseEvent.OnMouseClick:
                if (me.tar is SceneNodeMono || me.tar is CompVO)
                    onCompClick(me.tar, me.mouse);
                break;
            case MouseEvent.OnDragStart:

                if (me.mouse == 0)
                {
                    if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
                    {
                        CompVO oriComp = me.tar as CompVO;

                        if (oriComp != null && oriComp.CompType == EnumCompType.normal)
                        {
                            CopyComp(oriComp);
                        }
                    }
                    // 模型移动 通过坐标轴完成
                    //onStartDrag(me.tar);

                }
                break;
            case MouseEvent.OnDraging:
                //if (me.mouse == 0)
                //onDraging(me.tar);
                break;
            case MouseEvent.OnDragEnd:
                //if (me.mouse == 0)
                //onDragEnd(me.tar);
                break;
        }
    }

    /// <summary>组件点击</summary>
    void onCompClick(IMouseCtrl tar, int mouse)
    {
        //GameObject tarGO = (tar as SceneNodeMono).gameObject;
        //if (tarGO == null)
        //    return;

        if (MonoHelper.Instance.IsCruise)
        {
            return;
        }

        if (tar is SceneNodeMono)
        {
            GameObject tarGO = (tar as SceneNodeMono).gameObject;

            // 禁止旋转 和缩放
            if (!MonoHelper.Instance.IsCompEidtor)
            {
                MonoHelper.Instance.SetCanRotate(false);
                MonoHelper.Instance.SetCanScale(false);
            }

            if (mouse == 0)
            {
                Skin s = new Skin("UI_FairyGUI/ArtsWork", "ArtsWork", "MainUI");
                ViewMain vm = (ViewMain)DynamicActivityManager.Instance.Get(s);
                if (vm == null)
                {
                    return;
                }
                vm.ShowCurrentObj(tarGO);
                //SceneManager.Instance.DrawModelWire(tarGO);
                SceneManager.Instance.DrawMeshWire(tarGO);

                //MonoHelper.Instance.ShowAxis(tarGO.transform);

                CurSelect = tar as SceneNodeMono;
            }
            else if (mouse == 1 && !MonoHelper.Instance.m_bShowCmd)
            {
                VOView vo = new VOView
                {
                    ActivityType = typeof(ViewMat),
                    Data = tarGO,
                    isReplaceLastView = false
                };
                AppFacade.Instance.SendNotification(EventNames.APP_CHANGE_VIEW, vo);

                MonoHelper.Instance.HideAxis();
            }
        }
        else if (tar is CompVO && (tar as CompVO).CompType == EnumCompType.greenMesh)
        {
            GameObject tarGO = (tar as CompVO).gameObject;
            // 禁止旋转 和缩放
            if (!MonoHelper.Instance.IsCompEidtor)
            {
                MonoHelper.Instance.SetCanRotate(false);
                MonoHelper.Instance.SetCanScale(false);
            }
            if (mouse == 1 && !MonoHelper.Instance.m_bShowCmd)
            {
                VOView vo = new VOView
                {
                    ActivityType = typeof(ViewMat),
                    Data = tarGO,
                    isReplaceLastView = false
                };
                AppFacade.Instance.SendNotification(EventNames.APP_CHANGE_VIEW, vo);
            }
        }
        else if (tar is CompVO && (tar as CompVO).CompType == EnumCompType.normal)
        {
            MonoHelper.Instance.SetCanRotate(true);
            MonoHelper.Instance.SetCanScale(true);
        }
    }

    public void OnInputSubmit(string inputName)
    {
        GTextInput input = MonoHelper.Instance.GetInputByName(inputName);
        if (inputName == UICONST.IPT_INTERVAL)
        {
            float length;
            if (float.TryParse(input.text, out length))
            {
                if (CurSelect is CtrlPoint)
                {
                    CompVO comp = CtrlPointManager.Instance.GetCompByCtrlPoint(CurSelect as CtrlPoint);
                    if (comp.CompType == EnumCompType.wall)
                        comp.ResetPrefab(comp.CompCode, length);
                }
            }
        }
        Debug.Log("墙体长度改变: " + inputName + ", " + input.text);
    }

    public void OnBtnPress(BtnPressTime bpt)
    {
        Transform tarTran;

        if (CurSelect is CompVO)
        {
            tarTran = (curSelect as CompVO).transform;
            Vector3 vec = expediteKeyDic[bpt.BtnName].Key;
            switch (bpt.BtnName)
            {

                case UICONST.BTN_LT:
                case UICONST.BTN_RT:
                    vec = vec.GetScaledVector(bpt.PressTime * 1.5f);
                    tarTran.rotation = Quaternion.Euler((tarTran.rotation.eulerAngles + vec));
                    break;

                case UICONST.BTN_UP:
                case UICONST.BTN_DOWN:
                    vec = vec.GetScaledVector(bpt.PressTime * 0.02f);
                    float rotH = SceneManager.Instance.TheCameraCtrl.TheFocusCtrl.RotH / 180f * Mathf.PI;
                    Vector3 moveDelta = SongeUtil.MoveTowards(rotH, vec);
                    tarTran.position += vec;
                    break;

                case UICONST.BTN_SMAX:
                case UICONST.BTN_SMIN:
                case UICONST.BTN_XMAX:
                case UICONST.BTN_XMIN:
                case UICONST.BTN_YMAX:
                case UICONST.BTN_YMIN:
                case UICONST.BTN_ZMAX:
                case UICONST.BTN_ZMIN:
                    vec = vec.GetScaledVector(bpt.PressTime * 0.04f);
                    Vector3 scaleVec = tarTran.localScale - vec;
                    tarTran.localScale = new Vector3(Mathf.Clamp(scaleVec.x, 0.05f, 500f), Mathf.Clamp(scaleVec.y, 0.05f, 500f), Mathf.Clamp(scaleVec.z, 0.05f, 500f));
                    break;
            }
        }
        else if (curSelect is CtrlPoint)
        {
            tarTran = (curSelect as CtrlPoint).transform;
            switch (bpt.BtnName)
            {
                case UICONST.BTN_UP:
                    tarTran.position += Vector3.up;
                    CtrlPointManager.Instance.RefreshCompWallVO(curSelect as CtrlPoint);
                    break;
                case UICONST.BTN_DOWN:
                    tarTran.position += Vector3.down;
                    CtrlPointManager.Instance.RefreshCompWallVO(curSelect as CtrlPoint);
                    break;
            }
        }
    }

    public void OnBtnClick(string btnName, object param)
    {

        switch (btnName)
        {

            case UICONST.BTN_SAVE:
                SaveData(SceneManager.Instance.ToJson());
                break;
            case UICONST.BTN_POINT:
                if (EditState == EnumEditState.normal)
                    EditState = EnumEditState.addWall;
                else
                    EditState = EnumEditState.normal;
                break;

            case UICONST.BTN_GREENMESH:
                if (EditState == EnumEditState.normal)
                    EditState = EnumEditState.addGreenMesh;
                else
                    EditState = EnumEditState.normal;
                break;

            // 地块提交审核
            case UICONST.BTN_SUBMIT:
                SubmitBlock();
                break;
            case UICONST.BTN_REPLACE_ALL:
                {
                    SceneManager.Instance.ImportFBXs(
                        () =>
                        {
                            var count = SceneManager.Instance.BatchReplace();
                            if (count >= 0)
                            {
                                new WindowAlertDialog("批量替换已完成, 替换了" + count + "个模型").Show();
                            }
                            
                        }, null);
                }
                break;
        }

        Transform tarTran;
        if (CurSelect != null && CurSelect is MonoBehaviour)
        {
            MonoBehaviour tarMono = CurSelect as MonoBehaviour;
            if (tarMono != null)
            {
                tarTran = tarMono.transform;
                switch (btnName)
                {

                    case UICONST.BTN_ONE:
                        if (CurSelect is CompVO)
                            tarTran.localScale = Vector3.one;
                        break;

                    case UICONST.BTN_DELETE:
                        DeleteCurrent();
                        break;

                    case UICONST.BTN_REPLACE:
                        if (CurSelect is SceneNodeMono)
                        {
                            SceneNodeMono scn = CurSelect as SceneNodeMono;
                            // 导入新模型
                            SceneManager.Instance.ImportOneFBX(scn.gameObject.transform, () =>
                                {
                                    SceneManager.Instance.DeleteSceneNodeMono((CurSelect as SceneNodeMono), null);
                                });
                        }
                        break;
                    case UICONST.BTN_DISMANTLE:
                        CtrlPoint curSelectCtrlPoint = CurSelect as CtrlPoint;
                        if (curSelectCtrlPoint != null)
                        {
                            CompVO tarWall = CtrlPointManager.Instance.GetCompByCtrlPoint(curSelectCtrlPoint);
                            if (tarWall != null)
                                departWall(tarWall);
                        }
                        break;
                    case UICONST.BTN_CLONE:
                        if (CurSelect is SceneNodeMono)
                        {
                            SceneNodeMono scn = CurSelect as SceneNodeMono;

                            // 检查模型是否已经上传到服务器
                            SceneNode node = scn.sceneNode;

                            HttpService.GetDownloadURL(node.fileName, node.fileCrc, downloadUrl =>
                            {
                                SceneManager.Instance.OnCloneSceneNode(scn, scn.sceneNode);

                            }, (errorType, errorInfo) =>
                            {
                                WindowAlertDialog dlg = new WindowAlertDialog(node.fileName + "--:尚未保存到服务器，请保存之后再操作！");
                                dlg.Show();
                            });

                        }
                        break;
                }
            }

        }
    }


    public void DeleteCurrent(bool isBatch = false)
    {
        DeleteSel(CurSelect, isBatch);
    }

    public void AutoSetPosY()
    {
        var obj = CurSelect as MonoBehaviour;
        if (obj)
        {
            bool isHidden = MonoHelper.Instance.IsAxisHidden();
            if (!isHidden)
            {
                MonoHelper.Instance.HideAxis();
            }
            
            SongeUtil.SetPosYByRayCast(obj.transform);
            if (obj is CtrlPoint)
            {
                CtrlPointManager.Instance.RefreshCompWallVO(obj as CtrlPoint);
            }
            else
            {
                if (!isHidden)
                {
                    MonoHelper.Instance.ShowAxis(obj.transform);
                }
            }
        }
    }

    void DeleteSel(ISelectable sel, bool isBatch = false)
    {
        if (sel is CompVO)
        {
            RemoveComp(sel as CompVO);
        }
        else if (sel is CtrlPoint)
        {
            if (isBatch)
            {
                var comp = CtrlPointManager.Instance.GetCompByCtrlPoint(sel as CtrlPoint);
                //bool isRemoved = CtrlPointManager.Instance.RemoveCtrlPoint(sel as CtrlPoint);
                if (comp != null/* && !isRemoved*/)
                {
                    RemoveComp(comp);
                }
            }
            else
            {
                CtrlPointManager.Instance.RemoveCtrlPoint(sel as CtrlPoint);
            }
        }
        else if (sel is SceneNodeMono)
        {
            SceneManager.Instance.DeleteSceneNodeMono((sel as SceneNodeMono), null);
        }
        MonoHelper.Instance.HideAxis();
    }

    CompIconVO curSelectIcon;
    /// <summary>点击组件UI图标</summary>
    public void OnCompIconClick(CompIconVO icon)
    {
        curSelectIcon = icon;
        switch (EditState)
        {
            case EnumEditState.normal:
                EditState = EnumEditState.addComp;
                break;
            case EnumEditState.addComp:
                break;
            case EnumEditState.addWall:
                break;
            default:
                break;
        }
        if (CurSelect is CtrlPoint)
        {
            CompVO curWallComp = CtrlPointManager.Instance.GetCompByCtrlPoint(CurSelect as CtrlPoint);
            curWallComp.ResetPrefab(curSelectIcon.CompCode, CompLib.Instance.getDefaultWalllength(curSelectIcon.CompCode));
        }
    }

    public void ClearScene()
    {
        List<CompVO> compList = CompEditor.Instance.theCompList;
        for (int i = 0, length = theCompList.Count; i < length; i++)
        {
            GameObject.Destroy(compList[i]);
        }
        theCompList.Clear();
    }

    #region CompVO 组件管理

    public void OnSceneMouseDown(MouseEvent me)
    {
        if (me.tar == null)
        {
            if (me.mouse == 0)
            {
                if (EditState == EnumEditState.addComp)
                    addNewCompByMouse(curSelectIcon.CompCode, me.worldPoint);
                else if (EditState == EnumEditState.addWall)
                    addWallCtrlPoint(me.worldPoint);
                else if (EditState == EnumEditState.addGreenMesh)
                    addWallCtrlPoint(me.worldPoint);
            }
            else if (me.mouse == 1)
            {
                EditState = EnumEditState.normal;
                CurSelect = null;
            }
        }
        else if (me.mouse == 0 && me.tar is ISelectable)
        {
            ISelectable sel = me.tar as ISelectable;
            CurSelect = sel;

            Transform tf = null;
            if (me.tar is SceneNodeMono)
                tf = (me.tar as SceneNodeMono).transform;
            else if (me.tar is CompVO)
                tf = (me.tar as CompVO).transform;

            if (MonoHelper.Instance.m_bShowCmd)
            {
                MonoHelper.Instance.OnShowBuildingInfo(me.tar as SceneNodeMono);
            }

            MonoHelper.Instance.ShowAxis(tf);

            //if (sel is SceneNodeMono)
            //    CurSelect = sel;
            //else if (sel is CompVO && (sel as CompVO).CompType == EnumCompType.normal)
            //    CurSelect = sel;
        }
    }

    void addNewCompByMouse(string compCode, Vector3 pos)
    {
        CompVO comp = AddCompByCtrl(compCode, EnumCompType.normal, SongeUtil.GetMousePointOnHorizontal());
        float rotH = SceneManager.Instance.TheCameraCtrl.TheFocusCtrl.RotH - 90f;
        Vector3 CompRot = new Vector3(0, rotH, 0);
        comp.transform.localEulerAngles = CompRot;
        //comp.CreateModel();//CHECK 160916
        comp.ShowModel = true;
    }

    /// <summary>通过用户操作添加组件</summary>
    public CompVO AddCompByCtrl(string compCode, EnumCompType compType, Vector3 pos, bool isAutoSetY = true)
    {
        //CompVO c = new GameObject().AddComponent<CompVO>();
        CompVO c = addNewComp();
        c.CompType = compType;
        c.name = compCode;
        c.CompCode = compCode;
        c.transform.position = pos;
        if (isAutoSetY)
        {
            SongeUtil.SetPosYByRayCast(c.transform);
        }

        //c.transform.parent = typeFolderDic[c.CompType];
        if (c.CompType == EnumCompType.wall || c.CompType == EnumCompType.greenMesh)
        {
            if (c.theWallVO == null)
            {
                c.theWallVO = new WallVO();
                c.theWallVO.WallLength = CompLib.Instance.getDefaultWalllength(compCode);
                c.theWallVO.PointList = new List<Vector3>();
            }
        }
        return c;
    }
    /// <summary>通过地块存档添加组件</summary>
    public CompVO AddCompByConfig(JsonData compJD, bool _bSave = true)
    {
        CompVO newComp = addNewComp(_bSave);
        newComp.ReadJsonData(compJD);
        newComp.gameObject.name = newComp.CompType.ToString() + "_" + newComp.CompCode;
        newComp.ShowModel = true;
        newComp.CreatePointList();
        return newComp;
    }

    public List<CompVO> theCompList = new List<CompVO>();
    CompVO addNewComp(bool _bSave = true)
    {
        CompVO c = new GameObject().AddComponent<CompVO>();

        //c.gameObject.AddComponent<GizomBoxSelector>();
        if (_bSave)
        {
            theCompList.Add(c);
        }
        c.transform.parent = compFolder.transform;
        return c;
    }

    public void RemoveComp(CompVO comp)
    {
        theCompList.Remove(comp);
        if (comp.CompType == EnumCompType.wall || comp.CompType == EnumCompType.greenMesh)
        {
            CtrlPointManager.Instance.RemoveWall(comp);
        }
        GameObject.Destroy(comp.gameObject);
        GameObject.Destroy(comp);
        CurSelect = null;
    }

    /// <summary>
    /// Clear Component List
    /// </summary>
    public void ClearCompList()
    {
        theCompList.Clear();

        for (int i = compFolder.transform.childCount - 1; i > -1; --i)
        {
            GameObject.DestroyImmediate(compFolder.transform.GetChild(i).gameObject);
        }
    }

    public CompVO CopyComp(CompVO ori)
    {
        return AddCompByConfig(ori.ToJsonData());
    }

    #endregion

    #region 墙体编辑

    //CompVO curWallComp;
    void addWallCtrlPoint(Vector3 pos)
    {
        Vector3 clickPoint = SongeUtil.GetMousePointOnHorizontal();
        if (true) // isAutoSetY
        {
            SongeUtil.SetPosYByRayCast(ref clickPoint);
        }

        CompVO curWallComp;
        CtrlPoint curCtrlPoint = CurSelect as CtrlPoint;
        if (curCtrlPoint != null)
            curWallComp = CtrlPointManager.Instance.GetCompByCtrlPoint(curCtrlPoint);
        else
        {
            EnumCompType type;
            if (EditState == EnumEditState.addWall)
                type = EnumCompType.wall;
            else
                type = EnumCompType.greenMesh;
            curWallComp = AddCompByCtrl(CompLib.PrefabDefaultWall, type, clickPoint);
        }
        CurSelect = CtrlPointManager.Instance.AddCtrlPoint(curWallComp, clickPoint, curCtrlPoint, true, true);
    }

    void endCurWall()
    {
    }

    /// <summary>拆散墙体</summary>
    void departWall(CompVO wall)
    {

        if (wall != null && wall.CompType == EnumCompType.wall)
        {
            for (int iPoint = 0, nPoint = wall.theWallVO.PointList.Count - 1; iPoint < nPoint; iPoint++)
            {
                JsonData wallJD = wall.ToJsonData();
                Vector3 p0 = wall.theWallVO.PointList[iPoint];
                Vector3 p1 = wall.theWallVO.PointList[iPoint + 1];
                List<Vector3> pointList = new List<Vector3>() { p0, p1 };

                List<string> listRes = new List<string>();
                for (int j = 0, l = pointList.Count; j < l; j++)
                {
                    Vector3 point = pointList[j];
                    if (j == 0)
                        wallJD["firstPoint"] = JsonUtils.vecToStr(point);
                    listRes.Add(JsonUtils.vecToStr(point));
                }
                wallJD["pointList"] = JsonMapper.ToObject(JsonMapper.ToJson(listRes));


                CompVO newComp = AddCompByConfig(wallJD);
                //newComp.CreatePointList();

            }
            RemoveComp(wall);
        }

    }

    #endregion

    #region 拖拽
    Vector3 dragBias = new Vector3();//保证拖拽开始时组件位置不会跳变
    Vector3 dragStart = new Vector3();

    void onStartDrag(IMouseCtrl tar)
    {
        Transform tarTran;
        if (tar is SceneNodeMono)
            tarTran = (tar as SceneNodeMono).transform;
        else if (tar is CompVO)
            tarTran = (tar as CompVO).transform;
        else
            return;

        dragBias = tarTran.position - SongeUtil.GetMousePointOnHorizontal(Camera.main);
        dragStart = tarTran.position;
    }
    void onDraging(IMouseCtrl tar)
    {
        Transform tarTran;
        if (tar is SceneNodeMono)
            tarTran = (tar as SceneNodeMono).transform;
        else if (tar is CompVO && (tar as CompVO).CompType == EnumCompType.normal)
            tarTran = (tar as CompVO).transform;
        else
            return;

        Vector3 tarPoint = SongeUtil.GetMousePointOnHorizontal(Camera.main) + dragBias;
        if (tar != null)
        {
            tarTran.position = tarPoint;
        }
    }
    void onDragEnd(IMouseCtrl tar)
    {
    }

    #endregion

    /// <summary>云端保存</summary>
    public void SaveData(JSONNode jn, Action onSave = null, bool isShowSuccessDlg = true)
    {
        // 场景是否加载完成
        if (!SceneManager.Instance.IsSceneLoaded())
        {
            WindowAlertDialog dlg = new WindowAlertDialog("场景尚未加载完成，不能保存到云端！");
            dlg.Show();
            return;
        }

        // 场景材质是否重建完成 
        if (!MonoHelper.Instance.IsRebuildedMat)
        {
            WindowAlertDialog dlg = new WindowAlertDialog("材质重建过程中，不能保存到云端！");
            dlg.Show();
            return;
        }

        ViewMainContent vmc = (ViewMainContent)MonoHelper.Instance.GetViewContent(typeof(ViewMain));

        // 保存本地配置
        SaveToLocal(true, (filePath) =>
            {
                // 上传本地配置
                UpdateLocalArchives(filePath, (strFileInfo) =>
                    {
                        // 先上传场景模型
                        ResourceManager.Instance.UpdateLocalFile(() =>
                        {
                            // 加一层验证
                            ResourceManager.Instance.IsUpdateFinished(() =>
                            {
                                HttpService.CreateBlockEntity(vmc.currBlock.id, vmc.currBlock.working_id, jn, strFileInfo, blockEntity =>
                                {
                                    InfoTips.LogInfo("block update ok " + blockEntity.block_id);
                                    MonoHelper.Instance.vm.freshCreateBlockEntity = blockEntity;
                                    if (onSave != null)
                                        onSave();
                                    if (isShowSuccessDlg)
                                    {
                                        new WindowAlertDialog("保存场景列表到服务器成功！").Show();
                                    }
                                });

                            });
                        },
                            (errorType, errorInfo) =>
                            {
                                alertInfo.Show();
                                alertInfo.SetInformation("保存场景到服务器失败！请再试一次.\n" + errorType.ToString() + ": " + errorInfo.ToString());
                            });
                    });
            });

    }

    /// <summary>
    /// 本地存档文件信息 
    /// </summary>
    /// <returns></returns>
    private string UpdateLocalFileInfo()
    {
        JsonData fileJd = new JsonData();
        fileJd["data"] = new List<IJsonData>().ToJsonDataList();
        foreach (var key in MonoHelper.Instance.m_pTempFileInfo)
        {
            JsonData itemJD = new JsonData();
            itemJD["file"] = key.m_strName;
            itemJD["crc"] = key.m_strCrc;
            itemJD["date"] = key.m_strDate;
            fileJd["data"].Add(itemJD);
        }

        JSONNode jn = fileJd.ToSimpleJsonNode();
        return jn.ToString();
    }

    /// <summary>
    /// 上传本地存档文件
    /// </summary>
    /// <param name="_strFilePath"></param>
    private void UpdateLocalArchives(string _strFilePath,Action<string> _cb)
    {
        //TODO 上传文件
        //Debug.LogWarning("本地文件路径："+ _strFilePath);
        if (File.Exists(_strFilePath))
        {
            string strType = "ErrorType";

            int nIndex = _strFilePath.LastIndexOf('.');
            if (nIndex > 0 && nIndex < _strFilePath.Length - 1)
            {
                strType = _strFilePath.Substring(_strFilePath.LastIndexOf('.') + 1);
            }

            FileInfo file = new FileInfo(_strFilePath);

            HttpService.UploadFile(file.Name, file.GetFileCrc(), file.GetFileBytes(), strType,
                                   () =>
                                   {
                                       MonoHelper.TempFileInfo tfi = new MonoHelper.TempFileInfo();
                                       tfi.m_strCrc = file.GetFileCrc();
                                       tfi.m_strName = file.Name;
                                       tfi.m_strDate = DateTime.Now.ToString("yyyy-MM-dd-hh-mm");
                                       MonoHelper.Instance.m_pTempFileInfo.Add(tfi);

                                       string strFileInfo = UpdateLocalFileInfo();

                                       _cb(strFileInfo);
                                       Debug.LogWarning("本地文件配置:" + strFileInfo);
                                       //Debug.LogWarning("上传本地文件："+file.Name + "---成功！");
                                   },
                                   (errorType, msg) =>
                                   {
                                       Debug.LogError("上传本地文件: errorType: " + errorType.ToString() + ", msg: " + msg);
                                   });
        }
        else
        {
            _cb("Local File Dont Exist");
        }

    }

    WindowAlertDialog alertInfo = new WindowAlertDialog("");

    public void SaveToLocal(bool isUploadSave,Action<string> _cb = null)
    {
        ViewMainContent vmc = (ViewMainContent)MonoHelper.Instance.GetViewContent(typeof(ViewMain));
        LocalData localData = new LocalData();
        localData.data = SceneManager.Instance.ToJsonData();
        localData.user = SceneManager.Instance.CurUser;
        localData.cityName = vmc.currBlock.city_name;
        localData.blockID = vmc.currBlock.id.ToString();
        localData.blockName = vmc.currBlock.name;
        SaveToLocal(localData, isUploadSave,_cb);
    }

    void SaveToLocal(LocalData localData, bool isUploadSave, Action<string> _cb)
    {
        var sb = UtilsCommonS.StrBuilder;
        sb.Length = 0;
        sb.Append(SceneManager.DataPath);
        if (isUploadSave)
        {
            sb.Append("_UpLoadSave/");
        }
        sb.Append(UtilsCommonS.Time2String());
        sb.Append("__");

        int count = 0;
        while (count < 2)
        {
            sb.Append(localData.user);
            sb.Append("_");
            sb.Append(localData.cityName);
            sb.Append("_");
            sb.Append(localData.blockID);
            sb.Append("_");
            sb.Append(localData.blockName);

            if (0 == count)
            {
                sb.Append("/");
            }
            ++count;
        }
        sb.Append(".jd");

        string realPath = sb.ToString();
        InfoTips.LogInfo(realPath);

        System.IO.Directory.CreateDirectory((new System.IO.FileInfo(realPath)).Directory.FullName);
        var f = System.IO.File.Create(realPath);
        f.Close();
        File.WriteAllText(realPath, localData.ToJsonData().ToJson());

        // 回调：上传该文件到服务器
        if (_cb != null)
        {
            _cb(realPath);
        }
    }

    /// <summary>
    /// 地块提交审核：先保存到云端，再提交审核
    /// </summary>
    public void SubmitBlock()
    {
        ViewMainContent vmc = (ViewMainContent)MonoHelper.Instance.GetViewContent(typeof(ViewMain));
        JSONNode jn = SceneManager.Instance.ToJson();

        // 先上传场景模型
        ResourceManager.Instance.UpdateLocalFile(() =>
            {
                Debug.Log("WorkingID3:" + vmc.currBlock.working_id);

                HttpService.CreateBlockEntity(vmc.currBlock.id, vmc.currBlock.working_id, jn,"暂时先这样", blockEntity =>
                {

                    HttpService.SubmitBlockEntity(vmc.currBlock.id, blockEntity.id, jn, blockEntity1 =>
                    {
                        InfoTips.LogInfo("submit block ok " + blockEntity1.block_id);
                        new WindowAlertDialog("提交审核到服务器成功！").Show();

                        // 清除场景
                        SceneManager.Instance.CleanScene();

                        // 返回地块列表
                        VOView vo = new VOView
                        {
                            ActivityType = typeof(ViewBlock),
                        };
                        AppFacade.Instance.SendNotification(EventNames.APP_CHANGE_VIEW, vo);
                    });
                });
            },
            (errorType, errorInfo) =>
            {
                alertInfo.Show();
                alertInfo.SetInformation("保存场景到服务器失败！请再试一次.\n" + errorType.ToString() + ": " + errorInfo.ToString());
            }
            );
    }
}

class KeyValue
{
    public Vector3 Key;
    public float Value;
    public KeyValue(Vector3 key, float value)
    {
        Key = key;
        Value = value;
    }

}

public class BtnPressTime
{
    public string BtnName;
    public float PressTime;
    public BtnPressTime(string btnName, float pressTime)
    {
        BtnName = btnName;
        PressTime = pressTime;
    }
}

public class LocalData : IJsonData
{
    public JsonData data;
    public string user;
    public string cityName;
    public string blockID;
    public string blockName;

    public JsonData ToJsonData()
    {
        JsonData jd = new JsonData();
        jd["data"] = data;
        jd["user"] = user;
        jd["cityName"] = cityName;
        jd["blockID"] = blockID;
        jd["blockName"] = blockName;

        return jd;
    }

    public IJsonData ReadJsonData(JsonData jd)
    {
        data = jd.ReadJsonData("data");
        user = jd.ReadString("user");
        cityName = jd.ReadString("cityName");
        blockID = jd.ReadString("blockID");
        blockName = jd.ReadString("blockName");

        return this;
    }
}